package com.gitee.sparta.core.cluster.netty.codec;

import com.gitee.sparta.common.helpers.JsonHelper;
import com.gitee.sparta.core.bean.cluster.ClusterProtocol;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.List;

/**
 * <p>
 *      集群消息编解码器
 * </p>
 *
 * @author zyred
 * @since v 0.0.2
 */
@Slf4j
@ChannelHandler.Sharable
public final class ClusterProtocolCodec extends MessageToMessageCodec<ByteBuf, ClusterProtocol> {

    @Override
    protected void encode(ChannelHandlerContext ctx,
                          ClusterProtocol protocol, List<Object> list) {
        ByteBuf buffer = ctx.alloc().buffer();
        buffer.writeByte(protocol.getCmd());
        buffer.writeInt(protocol.getServerId());
        buffer.writeInt(protocol.getLeaderSid());
        // 对齐填充
        buffer.writeByte(0xff);
        Collection<String> topics = protocol.getTopics();
        byte[] topicBytes = JsonHelper.getJsonString(topics)
                .getBytes(StandardCharsets.UTF_8);
        buffer.writeInt(topicBytes.length);
        buffer.writeBytes(topicBytes);

        list.add(buffer);
    }


    @SuppressWarnings("unchecked")
    @Override
    protected void decode(ChannelHandlerContext ctx,
                          ByteBuf buf, List<Object> list) {
        ClusterProtocol cp = new ClusterProtocol();

        cp.setCmd(buf.readByte());
        cp.setServerId(buf.readInt());
        cp.setLeaderSid(buf.readInt());

        // 对齐填充
        buf.readByte();

        int dataLen = buf.readInt();
        byte[] data = new byte[dataLen];
        buf.readBytes(data);

        cp.setTopics(JsonHelper.readValue(data, Collection.class));
        list.add(cp);
    }
}
